package com.xhl.consul.tool.controller;

import com.alibaba.fastjson.JSON;
import com.commons.tools.utils.Result;
import com.xhl.consul.tool.entity.EmailObject;
import com.xhl.consul.tool.opentracing.OpentracingTest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @Author CazCen
 * @Date 2021/11/25 14:02
 */
@Api(tags = "用户信息")
@RestController
@RequestMapping("/test/info")
@Slf4j
public class RestTemplateController {

    @Value("${server.port}")
    private int port;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 通过 @RequestBody 注解，可以获取对方传过来的body内容，是一个json格式的东西
     */
    @PostMapping("/getTracing")
    public String tracing(HttpServletRequest request, HttpServletResponse response,
                          @RequestBody String body,
                          @RequestHeader("Content-Type") String ContentType,
                          @RequestHeader Map headerMap,
                          @RequestHeader MultiValueMap headerMultiValueMap) throws InterruptedException{

        log.info("body:{}, ContentType:{}, headerMap:{},headerMultiValueMap:{}",
                body,ContentType,headerMap,headerMultiValueMap);

//        MultiValueMap multiValueMap = JSON.parseObject(body, LinkedMultiValueMap.class);
//        log.info("multiValueMap:{}",multiValueMap);
//        log.info("multiValueMap-email:{}",multiValueMap.get("email"));
//        log.info("multiValueMap-body:{}",multiValueMap.get("body"));

        EmailObject emailObject = JSON.parseObject(body, EmailObject.class);
        log.info("emailObject:{}",emailObject);
        log.info("emailObject:{}",emailObject.getBody());

        Locale locale = request.getLocale();
        log.info("locale:{}",locale);

        String responseContentType = response.getHeader("Content-Type");
        log.info("responseContentType:{}",responseContentType);

        String headerContentType = request.getHeader("Content-Type");
        log.info("headerContentType:{}",headerContentType);


        log.info("request:{}",request);
        log.info("response:{}",response);



        String traceId = OpentracingTest.getTraceId();
        log.info("tracing - traceId:{}",traceId);


        // 往 HttpServletResponse 设置信息，调用者除了能获取到返回值 traceId 外，还能获取到其它信息
        // traceId 就相当于body了，所以返回的body一搬就是返回值，这也是为什么 HttpServletRequest
        // 和 HttpServletResponse 没有 body信息的原因
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setHeader("authorization","1234567890adb");

        // Cookie 一搬是用来记录某个特定的来访者是否访问过，故这里的 name 一般是用户信息生成的 token 作为key
        // 这里的用户并不一定是某个人或者某个账号，还可以是一个具体的物品，如是一个广告，将广告的id生成特点的token，
        // 然后可以统计该广告的访问次数
        // Cookie 有效期没有到时，用户可以不用输入账号和密码即可直接访问，使用用户的name和pwd生成特点的token


        String[] strArr = new String[6];
        for (String s : strArr) {
            log.info("sssssssss :{}",s);
        }


        // 下面的例子就是访问某个token的访问次数
        Cookie[] cookies = request.getCookies();
        log.info("cookies:{}",cookies);

        if(cookies.length > 0){
            for (Cookie cookie : cookies) {
                if(ObjectUtils.isEmpty(cookie)){
                    log.info("11111111 cookie is null");
                }else {
                    log.info("11111111 cookie:{}",cookie);
                }
            }
        }

        // 可以参考xxl-job 的 CookieUtil 类，然后在看看的token是怎么生成的,生成token是先到数据库查询出User信息，然后再将
        // User 信息转为json字符串，然后在去byte
        if(cookies.length > 0){
            for (Cookie cookie : cookies) {
                if(!StringUtils.isEmpty(cookie.getName()) && cookie.getName().equalsIgnoreCase("key1_user_token")){
                    Integer count = Integer.parseInt(cookie.getValue());
                    count = count + 1;
                    cookie.setValue(count.toString());
                    log.info("服务端：第几次访问:count:{}",count);
                    log.info("服务端：第几次访问:path:{}",cookie.getPath());
                }
            }
        }else {
            log.info("添加一个 Cookie token_name:key1_user_token");
            Cookie cookie1 = new Cookie("key1_user_token","1");
            response.addCookie(cookie1);
        }

        return traceId;

    }



    @PostMapping("/getInfo")
    @ApiOperation("获取信息")
    public void getInfo(){

        log.info("getInfo port:{}",port);

        MultiValueMap<String, String> email= new LinkedMultiValueMap<String, String>();
        email.add("email", "cazcen@163.com");
        email.add("subject", "圣诞节");
        email.add("body", "Hi Body 圣诞节 快乐");
        email.add("body", "Hi Body 圣诞节 快乐");


        ResponseEntity<String> stringResponseEntity =
                restTemplate.postForEntity("http://localhost:" + port + "/test/info/getTracing", email, String.class);

        String body = stringResponseEntity.getBody();

        String traceId = body;
        log.info("getInfo - traceId:{}",traceId);
    }



    @PostMapping("/getInfo2")
    @ApiOperation("获取信息2")
    public void getInfo2(){

        log.info("getInfo2 port:{}",port);

        MultiValueMap<String, String> email= new LinkedMultiValueMap<String, String>();
        email.add("email", "cazcen@163.com");
        email.add("subject", "圣诞节");
        email.add("body", "Hi Body 圣诞节 快乐");
        email.add("body", "Hi Body 圣诞节 快乐");

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity httpEntity = new HttpEntity(email,httpHeaders);


        ResponseEntity<String> stringResponseEntity =
                restTemplate.postForEntity("http://localhost:" + port + "/test/info/getTracing", httpEntity, String.class);

        String body = stringResponseEntity.getBody();

        String traceId = body;
        log.info("getInfo2 - traceId:{}",traceId);
    }





    @PostMapping("/getInfo3")
    @ApiOperation("获取信息3")
    public void getInfo3(HttpServletRequest request, HttpServletResponse response){


        Cookie[] cookies = request.getCookies();

        for (Cookie cookie : cookies) {
            log.info("cookie:{}",cookie);
        }


        EmailObject emailObject = new EmailObject();
        emailObject.setEmail("cazcen@163.com");
        emailObject.setSubject("圣诞节");
        emailObject.getBody();
        emailObject.getBody().add("Hi Body 圣诞节 快乐");
        emailObject.getBody().add("Hi Body 圣诞节 快乐");

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);


        HttpEntity httpEntity = new HttpEntity(emailObject,httpHeaders);


        ResponseEntity<String> stringResponseEntity =
                restTemplate.postForEntity("http://localhost:" + port + "/test/info/getTracing", httpEntity, String.class);

        String body = stringResponseEntity.getBody();

        String traceId = body;
        log.info("getInfo3 - traceId:{}",traceId);


        // 获取Cookie 信息，这里相当于客户端，可以取到Cookie信息
        log.info("stringResponseEntity:{}",stringResponseEntity);

    }


    @PostMapping("/getInfo4")
    @ApiOperation("验证Cookies的统计功能")
    public Result<String> getInfo4(HttpServletRequest request, HttpServletResponse response){

        Cookie[] cookies = request.getCookies();

        String count = "0";

        boolean theTokenExixt = false;
        for (Cookie cookie : cookies) {
            log.info("cookie:{}",cookie);
            log.info("cookie.value:{}",cookie);
            if(cookie.getName().equalsIgnoreCase("test_token_key")){
                log.info("cookie value:{}",cookie.getValue());
                count = cookie.getValue();
                cookie.setValue((Integer.toString(Integer.parseInt(cookie.getValue())+ 1) ));
                theTokenExixt = true;
                log.info("cookie value——2:{}",cookie.getValue());
                cookie.setMaxAge(Integer.MAX_VALUE);
                response.addCookie(cookie);
                break;
            }
        }
        if(!theTokenExixt){
            Cookie cookie = new Cookie("test_token_key", "1");
            response.addCookie(cookie);
        }
        return Result.ok(count);

    }

}
